// 声明该类所在的包
package com.score.interceptor;

// 导入 IOException 异常类，用于处理输入输出异常
import java.io.IOException;

// 导入 Servlet 过滤器相关的接口和类
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
// 导入 Servlet 注解，用于配置过滤器
import javax.servlet.annotation.WebFilter;
// 导入 HTTP 请求和响应相关的类
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// 导入自定义的常量类
import com.score.util.Constant;

/**
 * LoginFilter 类实现了 Servlet 的 Filter 接口，用于对特定的请求进行登录验证。
 * 该过滤器会拦截所有以 .html 结尾的请求，根据请求的 URI 判断是否需要进行登录验证，
 * 若用户未登录，则重定向到登录页面。
 */
@WebFilter(filterName = "loginFilter", urlPatterns = "/*.html")
public class LoginFilter implements Filter {

    /**
     * 初始化过滤器时调用的方法，在过滤器实例创建后执行一次。
     * 通常用于进行一些初始化操作，如加载配置信息等。
     *
     * @param filterConfig 过滤器配置对象，包含过滤器的初始化参数等信息
     * @throws ServletException 处理过程中可能抛出的 Servlet 异常
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 打印日志，提示过滤器已创建
        System.out.println("----------------------->过滤器被创建");
    }

    /**
     * 过滤器的核心方法，每次请求匹配到过滤器的 URL 模式时都会调用该方法。
     * 用于对请求进行预处理和对响应进行后处理。
     *
     * @param servletRequest 客户端请求对象
     * @param servletResponse 服务器响应对象
     * @param filterChain 过滤器链，用于将请求传递给下一个过滤器或 Servlet
     * @throws IOException 处理输入输出时可能抛出的异常
     * @throws ServletException 处理 Servlet 相关操作时可能抛出的异常
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 将 ServletRequest 转换为 HttpServletRequest，以便处理 HTTP 请求相关的操作
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        // 将 ServletResponse 转换为 HttpServletResponse，以便处理 HTTP 响应相关的操作
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 获取请求的 URI（统一资源标识符）
        String requestURI = request.getRequestURI();
        // 打印日志，输出当前请求的地址
        System.out.println("--------------------->过滤器：请求地址" + requestURI);

        // 判断请求的 URI 是否为无需登录验证的地址
        if(Constant.loginUrl.equals(requestURI) || requestURI.contains(Constant.AESSET) || Constant.LOGIN_URI.equals(requestURI) || Constant.STUDENT_LOGIN_URL.equals(requestURI)) {
            // 若为无需验证的地址，直接将请求传递给下一个过滤器或 Servlet
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            // 判断请求的 URI 是否为学生相关的地址
            if(Constant.STUDENT_INDEX.equals(requestURI) || Constant.MY_SCORE.equals(requestURI) ||
                    Constant.STUDENT_LOGINOUT_URL.equals(requestURI) || Constant.GET_MY_SCORE.equals(requestURI) ||
                    Constant.SCORE.equals(requestURI) || Constant.GET_MY_SCORE_COUNT.equals(requestURI)) {
                // 从会话中获取名为 "student" 的属性
                Object obj = request.getSession().getAttribute("student");
                // 判断学生是否已登录
                if(obj == null) {
                    // 若未登录，重定向到登录页面
                    response.sendRedirect("/login.html");
                    // 终止当前方法的执行
                    return;
                } else {
                    // 若已登录，将请求传递给下一个过滤器或 Servlet
                    filterChain.doFilter(servletRequest, servletResponse);
                }
            } else {
                // 从会话中获取名为 "user" 的属性
                Object obj = request.getSession().getAttribute("user");
                // 判断用户是否已登录
                if(obj == null) {
                    // 若未登录，重定向到登录页面
                    response.sendRedirect("/login.html");
                    // 终止当前方法的执行
                    return;
                } else {
                    // 若已登录，将请求传递给下一个过滤器或 Servlet
                    filterChain.doFilter(servletRequest, servletResponse);
                }
            }
        }
    }

    /**
     * 过滤器销毁时调用的方法，在过滤器实例被销毁前执行一次。
     * 通常用于进行一些资源释放操作，如关闭数据库连接等。
     */
    @Override
    public void destroy() {
        // 打印日志，提示过滤器已销毁
        System.out.println("----------------------->过滤器被销毁");
    }
}